package com.itbaizhan.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Map;

//放进spring容器中
@Controller
/*springMVC 控制器返回值可以为void String ModelAndView
* 我们可以通过控制器方法的返回值设置跳转的视图*/
public class MyController2 {
    /*返回值为void  跳转不灵活，很小用
    此时会跳转到名字是 前缀+方法路径名+后缀 的jsp页面  访问路径名与jsp的页名相同
    在访问时加路径就可以，因为视图解析器加了前缀与后缀
    http://localhost:8080/hello*/
    @RequestMapping("/hello")
    public void helloMVC(){
        System.out.println("hello");
    }


    /*返回值为String
此时会跳转到名字是 前缀+返回值+后缀 的jsp页面    访问的地址是路径：
http://localhost:8080/c2/hello2*/
    @RequestMapping("/c2/hello2")
    public String helloMVC2(){
        System.out.println("hello MVC");
        //方法执行后会跳转到/hello.jsp
        //return "hello";
        //方法执行后会跳转到/param.jsp
        return "param";
    }


    /*返回值为ModelAndView
这是SpringMVC提供的对象，该对象可以向request域设置数据并指定跳转的页面。
该对象中包含Model对象和View对象。
Model:向request域中设置数据
View：指定跳转页面*/
    @RequestMapping("/c2/hello3")
    public ModelAndView useMvc(){
        System.out.println("返回值类型为ModelAndView");
        //创建ModelAndView
        ModelAndView modelAndView = new ModelAndView();
        //获取model对象，本质是一个map
        Map<String, Object> model = modelAndView.getModel();
        //使用model对象向request域设置数据
        model.put("name","百战程序员");
        //使用view对象设置跳转的页面为/baizhan.jsp
        modelAndView.setViewName("baizhan");
        return modelAndView;

    }


    //当控制器返回值为ModelAndView时我们可以向request域设置数据，
    // 我们还有以下方法可以向request域设置数据：使用原生的HttpServletRequest   使用Model、ModelMap   使用Map集合
    @RequestMapping("/c2/hello4")
    public String setRequestModel(HttpServletRequest request){
        //key与value形式
        request.setAttribute("name","百战");
        return "baizhan";//返回的页面
    }
/*SpringMVC提供了Model接口和ModelMap类，
控制器方法添加这两个类型的参数，使用该参数设置数据，
该数据就会存到request域中。*/

    @RequestMapping("/c2/hello5")
    public String setRequestModel2(Model model, ModelMap modelMap){
        // 使用Model将数据存入request域
        model.addAttribute("name","百战2");
        // // 使用ModelMap将数据存入request域
       // modelMap.addAttribute("name","百战");
        return "baizhan";
    }

    /*Model接口底层就是一个Map集合，我们可以给控制器方法设置Map类型的参数，
    向Map中添加键值对，数据也会存到request域中。*/
    @RequestMapping("/c2/hello6")
    public String etRequestMap(Map map){
        map.put("name","百战3");
        return "baizhan";
    }

   // Session作用域表示在当前会话中有效。
    // 在SpringMVC中对于Session作用域传值，
    // 只能使用HttpSession对象来实现。
    //一般是在用户登录页面后，在页面顶部存放的“你好xxx用户”，不论到哪个页面都可以看到“你好xxx用户”
    @RequestMapping("/c2/hello7")
    public String setSession(HttpSession httpSession){
        httpSession.setAttribute("username","程序员");
        return "baizhan";

    }

    /*生命周期长，比较小用
    context作用域表示在整个应用范围都有效。
    在SpringMVC中对context作用域传值，
    只能使用ServletContext对象来实现。
    但是该对象不能直接注入到方法参数中，
    需要通过HttpSession对象获取。
    jsp页面中的applicationScope与java中的ServletContext相对应
    <h1>你好，${applicationScope.age}</h1>*/
    @RequestMapping("/c2/hello8")
    public String setContext(HttpSession httpSession){
        //获取ServletContext对象
        ServletContext context = httpSession.getServletContext();
        //context存放数据
        context.setAttribute("age","10");
        //session 存放数据
        httpSession.setAttribute("username","蓝天");
        return "baizhan";

    }

    //之前的案例，我们发现request域中的值可以传到jsp页面中，也就是通过视图解析器跳转到视图的底层是请求转发。

    //如果我们跳转时不想使用视图解析器，可以使用原生HttpServletRequest进行请求转发或HttpServletResponse进行重定向
    //使用原生的请求转发与重定向  直接用javaEE中的对象,没有使用视图解析器
    @RequestMapping("/c2/hello9")
    public void myForward1(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setAttribute("name","学生");
        //请求转发 数据可以发送到hello10
        //request.getRequestDispatcher("/c2/hello10").forward(request,response);
        //重定向(地址改变)  hello10取不到数据name
        response.sendRedirect("/c2/hello10");
    }

    @RequestMapping("/c2/hello10")
    public void myForward2(HttpServletRequest request){
        System.out.println("hello");
        System.out.println(request.getAttribute("name"));
    }

    //SpringMVC还提供了一种更简单的请求转发和重定向的写法
    @RequestMapping("/c2/hello11")
    public String myForward3(HttpServletRequest request){
        request.setAttribute("name","学生");
        //原生的请求转发  没有视图解析器
       // return "forward:/c2/hello10";
        //重定向  hello10取不到数据name
       return "redirect:/c2/hello10";
    }
}
/*SpringMVC默认情况下会在控制器执行完成后跳转到视图页面，
视图解析器能找到相应的视图，之前的404异常就是由于没有配置视图解析器导致找不到视图。

在SpringMVC中提供了13个视图解析器，用于支持不同的视图技术。
InternalResourceViewResolver是SpringMVC的默认视图解析器，
用来解析JSP视图。
在resources下的springmvc.xml配置
<!-- 视图解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <!-- 视图前缀 -->
  <property name="prefix" value="/" />
  <!-- 视图后缀 -->
  <property name="suffix" value=".jsp" />
</bean>*/